﻿using IOA.MES.Client.Common;
using IOA.MES.Client.Common.SocketUtils;
using IOA.MES.Client.Models.Response;
using IOA.MES.Client.Settings;
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace IOA.MES.Client.Sort
{
    /// <summary>
    /// SortIndex.xaml 的交互逻辑
    /// </summary>
    public partial class SortIndex : Window
    {
        private SocketClient socketClient;
        private bool deviceReady;

        private List<SortStack> stacks { get; set; } = new List<SortStack>();

        public SortIndex()
        {
            InitializeComponent();
        }

        #region 初始化数据
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            txtTrueName.Content = BaseEnv.UserInfo.TrueName;
            InitDuties();
            InitMachines();
            InitStacks(true);
            TryConnectDevice();

            InitForms();
        }

        public void InitDuties()
        {
            var duties = BaseEnv.InvokeApi<QueryDutiesResponse>("/api/Auth/QueryDuties", new { }).Data.Duties;

            cbDuties.ItemsSource = duties;
            cbDuties.DisplayMemberPath = "DutyName";
            cbDuties.SelectedValuePath = "DutyId";

            if (duties.Any())
            {
                cbDuties.SelectedIndex = 0;
            }
        }

        public void InitMachines()
        {
            var machines = BaseEnv.InvokeApi<QueryMachinesResponse>("/api/Machine/QueryMachines", new { MachineType = (int)MachineType.Sort }).Data.Machines;
            cbMachines.ItemsSource = machines;
            cbMachines.DisplayMemberPath = "MachineName";
            cbMachines.SelectedValuePath = "MachineId";

            if (machines.Any(_ => _.MachineId == BaseEnv.MachineId))
            {
                cbMachines.SelectedIndex = machines.FindIndex(_ => _.MachineId == BaseEnv.MachineId);
            }
            else
            {
                CommonMessage.Alert(this, "Vui lòng chọn lại thiết bị trong cài đặt hệ thống ngay bây giờ\r\n请先在系统设置中重新选择设备\r\nPlease reselect the device in the system settings now"); ;
                new SettingsIndex().ShowDialog();
            }
        }

        public void InitStacks(bool getNew = false)
        {
            if (getNew)
            {
                stacks = BaseEnv.InvokeApi<GetSortMachineStatusResponse>("/api/Machine/QuerySortStacks", new
                {
                    MachineId = Convert.ToInt32(cbMachines.SelectedValue)
                }).Data.Stacks;
            }

            for (var i = 1; i <= 9; i++)
            {
                var stack = stacks.FirstOrDefault(_ => _.StackNo == i);
                var grid = this.FindName($"grid{i}") as Grid;
                grid.Children.Clear();
                if (stack == null)
                {
                    continue;
                }

                grid.RowDefinitions.Clear();
                grid.RowDefinitions.Add(new RowDefinition());
                var lblSortNo = new TextBlock
                {
                    Text = $"块数：{stack.SortNo}",
                    FontSize = 50,
                    Foreground = stack.LastSort ? new SolidColorBrush(Color.FromRgb(255, 87, 34)) : new SolidColorBrush(Color.FromRgb(1, 170, 237)),
                    TextAlignment = TextAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center
                };
                lblSortNo.SetValue(Grid.RowProperty, 0);
                grid.Children.Add(lblSortNo);
                foreach (var rule in stack.Rules)
                {
                    grid.RowDefinitions.Add(new RowDefinition());
                    var label = new TextBlock
                    {
                        Text = $"{rule.Key}：{rule.Value}",
                        FontSize = 18,
                        TextAlignment = TextAlignment.Left,
                        VerticalAlignment = VerticalAlignment.Center,
                        Margin = new Thickness(10, 0, 0, 0)
                    };
                    label.SetValue(Grid.RowProperty, stack.Rules.IndexOf(rule) + 1);
                    grid.Children.Add(label);
                }
            }
        }

        private void Menu_Click(object sender, RoutedEventArgs e)
        {
            switch (((MenuItem)sender).Name)
            {
                case "btnSettings":
                    new SettingsIndex().ShowDialog();
                    break;
                case "btnSorterSettings":
                    if (new WinSortSetting().ShowDialog() == true)
                    {
                        TryConnectDevice();
                    }
                    break;
                case "btnLogout":
                    new LoginWindow(false).Show();
                    this.Hide();
                    break;
                case "btnAbout":
                    MessageBox.Show($"VinaSolarMes Product Version:{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion}");
                    break;
            }
        }
        private void InitForms(bool flowback = false)
        {
            txtCode.Text = "";
            txtCode.Focus();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }
        #endregion

        /// <summary>
        /// 连接扫码器
        /// </summary>
        private void TryConnectDevice()
        {
            var ipAddress = BaseEnv.GetStorage("SortIpAddress") ?? string.Empty;
            var port = BaseEnv.GetStorage("SortPort") ?? string.Empty;
            if (!string.IsNullOrWhiteSpace(ipAddress) && !string.IsNullOrWhiteSpace(port))
            {
                socketClient = new SocketClient(this, ipAddress, Convert.ToInt32(port), OnTcpStatusChange, OnDataReceived, Encoding.ASCII.GetBytes("  ").ToList(), 10000);
                socketClient.Connect();
            }
        }

        /// <summary>
        /// 扫码枪连接状态变化
        /// </summary>
        public void OnTcpStatusChange(bool connected)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                if (connected)
                {
                    lbStatus.Content = "已连接";
                    lbStatus.Foreground = new SolidColorBrush(Colors.Green);
                }
                else
                {
                    lbStatus.Content = "已断开";
                    lbStatus.Foreground = new SolidColorBrush(Colors.Red);
                }
            }));
        }

        public void OnDataReceived(List<byte> data)
        {
            Dispatcher.Invoke(new Action(() =>
            {
                var text = Encoding.ASCII.GetString(data.ToArray());
                if (text.StartsWith("AA"))
                {
                    deviceReady = true;
                    lbModuleStatus.Content = "组件已到位";
                    lbModuleStatus.Foreground = new SolidColorBrush(Colors.Green);
                }
            }));
        }

        private void InitModule()
        {
            Dispatcher.Invoke(new Action(() =>
            {
                var clearData = Encoding.ASCII.GetBytes("  ").ToList();
                socketClient.Send(clearData);

                deviceReady = false;
                lbModuleStatus.Content = "组件未到位";
                lbModuleStatus.Foreground = new SolidColorBrush(Colors.Red);
            }));
        }

        /// <summary>
        /// 扫描条码
        /// </summary>
        private void txtCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtCode.Text.Trim()) || e != null && e.Key != Key.Enter)
            {
                return;
            }
            else if (!deviceReady)
            {
                CommonMessage.Alert(this, "组件尚未到位");
                txtCode.Text = "";
                return;
            }

            var request = new
            {
                MachineId = Convert.ToInt32(cbMachines.SelectedValue),
                BarCode = txtCode.Text.Trim()
            };
            var response = BaseEnv.InvokeApi<SortResponse>("/api/Machine/Sort", request);
            if (response.ErrCode != 200)
            {
                mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                mediaElResult.Play();
                CommonMessage.Alert(this, response.ErrMsg);
                InitForms();
                return;
            }
            CommonMessage.Log(LogLevel.Info, $"分拣成功：{txtCode.Text.Trim()}");

            stacks = response.Data.SortStacks;
            lblWorkOrderNo.Content = response.Data.WorkOrderNo;
            InitForms();
            InitStacks();

            mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Success.wav");
            mediaElResult.Play();

            var lastStack = stacks.FirstOrDefault(_ => _.LastSort);
            if (lastStack != null && string.Equals(Convert.ToString(lbStatus.Content), "已连接"))
            {
                socketClient.Send(Encoding.ASCII.GetBytes(lastStack.StackNo.ToString("00")).ToList());

                Thread.Sleep(500);
                InitModule();
            }
        }

        private void ClearClick(object sender, RoutedEventArgs e)
        {
            var grid = (sender as Control).Parent as Grid;
            var stackNo = Convert.ToInt32(grid.GetValue(Grid.RowProperty)) * 5 + Convert.ToInt32(grid.GetValue(Grid.ColumnProperty)) + 1;

            if (System.Windows.Forms.MessageBox.Show($"Bạn có chắc chắn muốn trống không?\r\n确定要清空吗？\r\nAre you sure you want to empty?\r\n{stackNo}", "清空提示", System.Windows.Forms.MessageBoxButtons.YesNo)
                != System.Windows.Forms.DialogResult.Yes)
            {
                return;
            }

            var request = new
            {
                MachineId = Convert.ToInt32(cbMachines.SelectedValue),
                StackNo = stackNo
            };
            var response = BaseEnv.InvokeApi<ClearSortStackResponse>("/api/Machine/ClearSortStack", request);
            if (response.ErrCode != 200)
            {
                mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                mediaElResult.Play();
                CommonMessage.Alert(this, response.ErrMsg);
                InitForms();
                return;
            }
            CommonMessage.Log(LogLevel.Info, $"清空成功：{stackNo}");

            stacks = response.Data.Stacks;
            InitStacks();
            InitForms();
        }
    }
}
